<html>
<head>
   <script src="../../Grid/GridE.js"> </script>
</head>
<body class="Tutorial">
   <script>

// -----------------------------------------------------------------------------------------------------------

Grids.OnContextMenu = function(G,row,col,result){
if(row.id==1 && col=="MENU"){
   if(result=="Clear") G.SetValue(row,col,"",1);
   if(result=="Edit") G.Prompt("Enter new value",G.GetString(row,col),function (val){ if(val!=null) G.SetString(row,col,val,1); } );
   if(result=="Auto") G.SetValue(row,col,"API OnContextMenu",1); 
   }
}

// -----------------------------------------------------------------------------------------------------------

Grids.OnRightClick = function(G,row,col,x,y,event){
G.CloseDialog(); // Closes previous dialog in grid if any
if(row.id==4 && col=="MENU"){
   G.Dialog = ShowMenu({ Items:[
         { Name:"Clear", Text:"Clear value", OnClick:function(){ G.SetValue(row,col,"",1); } },
         { Name:"Edit", Text:"Edit value", OnClick:function(){ G.Prompt("Enter new value",G.GetString(row,col),function (val){ if(val!=null) G.SetString(row,col,val,1); } ); } },
         { Name:"Auto", Text:"Set original value", OnClick:function(){ G.SetValue(row,col,"Custom OnRightClick",1); } }
      ]},{
         Tag:G.GetCell(row,col),Align:"above right",Y:-10
         });
   return true;
   }
}
if(Grids.Tablet) Grids.OnLongClick = Grids.OnRightClick;

// -----------------------------------------------------------------------------------------------------------

Grids.OnTip = function(G,row,col,tip,cx,cy,x,y){
if(row.id==4 && col=="TIP"){
   return "This is tip generated by OnTip event handler for cell ["+row.id+","+col+"]";
   }
return tip;   
}

// -----------------------------------------------------------------------------------------------------------

Grids.OnHint = function(G,row,col,hint){
if(row.id==4 && col=="HINT"){
   return "This is hint generated by OnHint<br> event handler for cell ["+row.id+","+col+"]:<br><div style='color:red;'>"+hint+"</div>";
   }
return hint;   
}

// -----------------------------------------------------------------------------------------------------------
// Shows custom html dialog without any TreeGrid built-in method
function ShowHtmlDialog(G,row,col,x,y){
if(G.Dialog) { var ret = G.Dialog.Row==row&&G.Dialog.Col==col; G.CloseDialog(); if(ret) return true; } // Closes the dialog only if clicked again to the same button
G.EndEdit(1);    // Finishes editing if any

// --- Creates the custom calendar, here just simple input ---
var d = document.createElement("div"), s = d.style;
s.position = "absolute";
s.left = (x+2)+"px";
s.top = (y+2)+"px";
s.background = "silver";
s.border = "1px solid black";
s.zIndex = "300";
d.innerHTML = "<div>Custom calendar dialog example</div><input style='width:200px' value='"+G.GetString(row,col)+"'>";
d.onclick = CancelEvent; // suppresses grid OnClick handler
document.body.appendChild(d);
d.lastChild.focus();
d.lastChild.select();
d.lastChild.onkeydown = function(ev){
   if(!ev) ev = event;
   var key = ev.keyCode ? ev.keyCode : ev.charCode;
   if(key==13) { // Enter - save 
      G.SetStringEdit(row,col,this.value,1);
      G.CloseDialog();
      }
   if(key==27){ // Esc - cancel
      G.CloseDialog();
      }     
   return true;
   }

// --- Sets the custom calendar as grid dialog with Close method called to close the calendar on demand ---
G.Dialog = { Close: function(){ document.body.removeChild(d); }, Row:row, Col:col, Grid:G } 

return true;
}
// -----------------------------------------------------------------------------------------------------------
// Shows custom menu using TreeGrid JSON menu for given cell
function ShowCustomMenu(G,row,col){
G.EndEdit(1);    // Finishes editing if any
var M = {Default:{Bool:1},Items:"|A|B|C|D",Buttons:["Ok"]};
M.OnSave = function(I,result){ G.SetString(row,col,result.join("+"),1); }
var P = {Align:"right below"};
M = G.ShowMenu(row,col,M,P,null,G.GetValue(row,col).split("+"));
return true;
}
// -----------------------------------------------------------------------------------------------------------
// Shows custom dialog by ShowDialog
function ShowCustomDialog(G,row,col){
G.EndEdit(1);    // Finishes editing if any

var M = {Body:"<div style='background:yellow'><div>Custom edit dialog example</div><input style='width:200px' value='"+G.GetString(row,col)+"'></div>"};

M = G.ShowDialog(row,col,M,0); if(!M) return true;

var I = M.Tag.getElementsByTagName("input")[0];
I.onkeydown = function(ev){
   if(!ev) ev = event;
   var key = ev.keyCode ? ev.keyCode : ev.charCode;
   if(key==13) { // Enter - save 
      G.SetString(row,col,this.value,1);
      G.CloseDialog();
      CancelEvent(ev);
      }
   if(key==27){ // Esc - cancel
      G.CloseDialog();
      }  
   }
I.focus();
I.select();
return true;
}
// -----------------------------------------------------------------------------------------------------------
// Shows standard TreeGrid calendar as custom dialog for no date cell, by ShowCalendar
function ShowCustomCalendar(G,row,col){
var d = Get(row,col); d = d ? StringToDate(d) : (new Date()).setUTCHours(0,0,0)-0;
var F = function(n){
   if(n!="") n = DateToString(n,"yyyy-MM-dd");
   G.SetValue(row,col,n,1);
   }
var P = {Align:"left above"};
M = G.ShowCalendar(row,col,null,P,F,d);
return true;
}
// -----------------------------------------------------------------------------------------------------------
// Shows popup grid for given cell
function ShowCustomGrid(G,row,col){
var v = G.GetValue(row,col).split(" "), s = "";
for(var i=0;i<v.length;i++){
   var vi = v[i].split("=");
   s += "<I N='"+vi[0]+"' V='"+(vi[1]?vi[1]:"")+"'/>";
   }
s = "<Grid><Cols><C Name='N' Type='Text' EditMask='\w*' Width='80'/><C Name='V' Type='Int' CanEmpty='1' Width='80'/></Cols><Header N='Name' V='Value'/>"
  + "<Toolbar Cells='L,ADD,CANCEL,OK'"
  +   " LRelWidth='1' LType='Html'"
  +   " ADD='Add' ADDButton='Button' ADDWidth='50' ADDOnClick='AddRowEnd'"
  +   " CANCEL='Cancel' CANCELButton='Button' CANCELWidth='50' CANCELOnClick='Grid.ParentDialog.Close();return 1;'"
  +   " OK='Ok' OKButton='Button' OKWidth='50' OKOnClick='SaveCustomGrid(Grid);return 1;'"
  + "/>"
  + "<Body><B>"+s+"</B></Body></Grid>";
var P = G.ShowPopupGrid(row,col,s);
}
// -----------------------------------------------------------------------------------------------------------
// Saves values from custom popup grid to the source cell
function SaveCustomGrid(P){
P.EndEdit(1);         // Finishes editing if any
var M = P.ParentDialog, row = M.Row, col = M.Col, G = P.ParentGrid;
var v = [];
for(var r=P.GetFirst();r;r=P.GetNext(r)) if(!r.Deleted){
   var n = Get(r,"N"), x = Get(r,"V");
   if(n) v[v.length] = n + (x?"="+x:"");
   }
G.SetValue(row,col,v.join(" "),1);
M.Close();
}
// -----------------------------------------------------------------------------------------------------------
   </script>
      
   <style>

      /* Tutorial shared styles */
      .Tutorial h1,.Tutorial h2,.Tutorial ul,.Tutorial .Desc,.Tutorial .Path,.Tutorial .Xml { max-height:999999px; }
      .Tutorial h1 { font:30px Arial; padding:5px 0px 5px 0px; margin:0px; text-align:center; }
      .Tutorial h2 { font:15px Arial; padding:0px; margin:0px 0px 10px 0px; text-align:center; color:#757575; }
      .Tutorial h3,.Tutorial h4 { display:inline-block; font:bold 15px Arial; padding:0px 5px 0px 5px; border-radius:2px; color:black; margin:2px; font-style:normal; color:#333; }
      .Tutorial h3 { background:#EE9; border:1px solid #DD8; }
      .Tutorial h4 { background:#BDE; border:1px solid #ACD; }
      .Tutorial a { text-decoration:underline; }      
      .Tutorial li { padding-bottom:8px; }
      .Tutorial ul { margin:6px 0px 0px 20px; font:13px Arial; }
      .Tutorial > ul { margin-left:0px; padding-left:15px; clear:both; }
      .Tutorial ul b { color:#0585B9; }
      .Tutorial .Path { font:normal 12px Arial; color:#0585B9; }
      .Tutorial .Path b { color:#D73938; }
      .Tutorial .Path u { text-decoration:none; color:black; font-weight:bold; padding:0px 2px 0px 2px; }
      .Tutorial .Xml { margin-bottom:6px; font-size:12px; color:#757575; }
      .Tutorial .Border { border:1px solid #dfdfdf; padding:10px 20px 10px 20px; margin:0px 8px 20px 0px; min-width:100%; box-sizing:border-box; }
      .Tutorial .Main { }

      /* Styles specific for the example */
      .Red { background:#FAA; }

   </style>

   <center class="Path"><script>document.write(location.href.replace(/(.*)(\/Tutorials\/)([^\/]+)\/([^\/]+)$/,"$2<b>$3</b>/$4").replace(/([^<]|^)(\/|\.)/g,"$1<u>$2</u>"));</script></center>
   <h1>9. Cell Events, Menu, Tip, Hint and Custom dialogs</h1>
   <h2>Cell API and XML events, popup Menu, tooltip, Hint and showing custom dialogs by API</h2>

   <center class="Border" id="Border">
      <div class="Xml">Source: <a href='09-Cell_events.js'>09-Cell_events.js</a></div>
      <div class="Main" style='width:100%; height:227px;'>
         <bdo Debug='check' Data_Url='09-Cell_events.js'></bdo>
      </div>
   </center>

   <ul>
      <li>
         <h3>Menu</h3> attribute defines popup menu shown on right click to the cell or row.<br />
         The menu can be defined as first character separated array or by complete TreeGrid JSON menu definition.<br />
         The selected item can be got in API event <b>OnContextMenu</b> or in the JSON menu events <b>OnSave</b> or <b>OnClick</b>.<br />
         The popup menu can be also shown by custom way by method API <b>ShowPopup</b> or <b>ShowMenu</b> in any event handler like <b>OnRightClick</b>.<br />
      </li>
      <li>
         <h3>Tip</h3> attribute defines tooltip for the cell, or for cell part like side button or panel icon.<br />
         There can be also defined more tooltips for particular cell value (e.g. for button on/off).<br />
         The tip content supports any HTML code including images or more lines.<br />
         Is possible also predefine tooltip position where it will be shown by <b>TipPosition</b> attribute.<br />
         When the Tip attribute is 1, it shows actual cell value as tooltip.<br />
         The tooltip content can be also created dynamically in API event <b>OnTip</b>.
      </li>
      <li><h4>Hint</h4> is feature that shows the whole content of overflowed cell as popup directly above the cell.<br />
      It is turn on by default for all cell types except Radio, Gantt, Chart, Abs and Icon and can be also disabled by <b>ShowHint</b>='0'.<br />
      The text shown can be dynamically changed or created by API event <b>OnHint</b>.
      </li>
      <li><h4>Custom dialog</h4> like calendar can be defined in this way:
         <ul>
         <li>
            Define the XML event (in cell or column) for click to the button, for calendar it is <b>OnClickSideDate</b>, for defaults <b>OnClickSideDefaults</b> and for custom Button/Icon <b>OnClickSideButton</b> or <b>OnClickSideIcon</b>.<br />
            This event has four parameters: Grid, Row, Col, Event, the event contains also the position of mouse click.
         </li>
         <li>
            In this event handler show the custom dialog on given position, for the cell or on mouse click position.<br />
            Close any previous dialog in grid by <b>Grid.CloseDialog()</b>;<br />
            The created dialog object (or any other custom object) assign to <b>Grid.Dialog</b> property. <br />
            This object should define its <b>Close</b> method that is called by grid when the dialog should be closed on demand (for example if a user clicks to another cell).<br />
            For example: Grid.Dialog = { Close:function(){ CloseMyDialog(); } }
         
         </li>
         <li>
            Or create the custom dialog using built in TreeGrid API method like <b>ShowMenu</b>, <b>ShowDialog</b>, <b>ShowCalendar</b> or <b>ShowPopupGrid</b>.<br />
            In this case you don't need to care about closing the dialog.
         </li>
         <li>
            Optionally finish editing by <b>Grid.EndEdit(1)</b>; or cancel editing by Grid.EndEdit(0);
         </li>
         </ul>
      </li>
   </ul>

   <!-- Google Analytics code run once for trial -->
   <script>
      var TGTrial = document.cookie.match(/TGTrialCells\s*=\s*(\d+)/), TGIndex = 256;
      if(!TGTrial||!(TGTrial[1]&TGIndex)) setTimeout(function(){
         var n = "RunTrialGridCells9", d = (new Date((new Date).getTime()+31536000000)).toUTCString(); document.cookie = "TGTrialCells="+((TGTrial?TGTrial[1]:0)|TGIndex)+";expires="+d;
         var u = document.cookie.match(/TGTrialUsed\s*=\s*(\d+)/); u = u ? u[1]-0+1 : 1; if(u<=11) document.cookie = "TGTrialUsed="+u+";path=/;expires="+d;
         var s = "<div style='width:0px;height:0px;overflow:hidden;'><iframe src='http"+(document.location.protocol=="https"?"s":"")+"://www.treegrid.com/Stat/GA.html?productName="
               +(u==1||u==3||u==5||u==10?"UsedTrial"+u:n)+"' onload='var T=this;setTimeout(function(){document.body.removeChild(T.parentNode.parentNode);},1000);'/></div>";
         var F = document.createElement("div"); F.innerHTML = s; document.body.appendChild(F);
         },100);
   </script>
</body>
</html>